import React, {PropsWithChildren, useEffect, useMemo, useState} from 'react'
import {View} from "@tarojs/components";
import styles from "./procurementDetail.module.sass"
import Taro, {useLoad} from "@tarojs/taro";
import {
    addProcurementItemFromBarcode, addProcurementItemsFromSubGoodsKeyList, deleteProcurement,
    deleteProcurementItem,
    deleteProcurementItemSub,
    getProcurementDetail,
    ProcurementItem,
    receiptProcurement,
    submitProcurement,
    updateProcurementItemAmount,
    updateProcurementItemNote,
    updateProcurementItemSubAmount,
    updateProcurementItemSubNote
} from "../apis/ProcurementApi";
import procurementPageStackStore from "../store/ProcurementPageStackStore";
import employeeStore from "../store/EmployeeStore";
import MyNavigationBar, {useMyNavigationBarHeight} from "../components/MyNavigationBar";
import {Button, Cell, CellGroup, SafeArea, Space} from "@nutui/nutui-react-taro";
import {DATE_WITH_HOUR_MINUTE_FORMATER, DATE_WITH_TIME_FORMATER} from "../utils/Date";
import {Add, ArrowRight, Top} from "@nutui/icons-react-taro";
import ExportToExcelConfigurationDialog from "../components/ExportToExcelConfigurationDialog";
import {ExcelColumn, exportToWorkbook, saveAndOpenWorkbook} from "../utils/ExcelUtils";
import {OffsetDateTime} from "@js-joda/core";
import OrderListItem from "../components/OrderListItem";
import ArrayUtils from "@zxy-cn/array-utils";
import ScanBarcodeButton from "../components/ScanBarcodeButton";
import {barcodeRepeated, scanSuccess} from "../utils/ScanCodeUtils";
import SelectGoodsPopup from "../components/SelectGoodsPopup";
import {observer} from "mobx-react";

export interface ProcurementDetailProps extends PropsWithChildren {

}

const PROCUREMENT_ITEMS_EXPORT_COLUMNS_KEY = "PROCUREMENT_ITEMS_EXPORT_COLUMNS"

const columns: ExcelColumn<ProcurementItem>[] = [
    {
        key: "barcode",
        header: "条码",
    }, {
        key: "subGoodsNumber",
        header: "子商品编码",
        renderToString: item => item.subGoods?.number ?? ""
    }, {
        key: "subGoodsName",
        header: "子商品名称",
        renderToString: item => item.subGoods?.name ?? ""
    },
    {
        key: "name",
        header: "名称",
    }, {
        key: "amountInOrder",
        header: "数量",
        renderToString: item => {
            return `${item.amountInOrder}${item.unit?.name ?? ""}`
        }
    },
    {
        key: "price",
        header: "零售价",
    },
    {
        key: "purchasePrice",
        header: "采购价",
    },
    {
        key: "note",
        header: "备注",
    },
    {
        key: "boxSpecification",
        header: "箱规",
    },
];

const ProcurementDetail: React.FC<ProcurementDetailProps> = ({}) => {
    const [title, setTitle] = useState("采购详情")
    const [procurementId, setProcurementId] = useState<number>()
    const data = procurementPageStackStore.detail
    useLoad((params) => {
        setProcurementId(params.id)
    })
    useEffect(() => {
        if (procurementId) {
            Taro.showLoading()
            getProcurementDetail(procurementId)
                .then(response => {
                    procurementPageStackStore.setDetail(response.data)
                    setTitle(response.data.supplier.name + "订单明细")
                }).finally(() => {
                Taro.hideLoading()
            });
        }
    }, [procurementId]);

    const canDelete = useMemo(() => {
        return employeeStore.hasAuthority("采购_删除") && data && !data.submittedDateTime
    }, [employeeStore.employee, data]);

    const canSubmit = useMemo(() => {
        return employeeStore.hasAuthority("采购_下单") && !!data && !data.submittedDateTime
    }, [employeeStore.employee, data]);

    const canReceipt = useMemo(() => {
        return employeeStore.hasAuthority("采购_入库_入库") && !!data && !data.receiptDateTime && !!data.submittedDateTime
    }, [employeeStore.employee, data]);

    const canEdit = useMemo(() => {
        return employeeStore.hasAuthority("采购_修改") && (canReceipt || canSubmit)
    }, [canSubmit, canReceipt, employeeStore.employee]);

    const [selectGoodsPopupVisible, setSelectGoodsPopupVisible] = useState(false)

    const [exportToExcelDialogVisible, setExportToExcelDialogVisible] = useState(false)

    function scrollToBottom() {
        Taro.pageScrollTo({
            scrollTop: 999999,
        })
    }

    let myNavigationBarHeight = useMyNavigationBarHeight();
    const [deleting, setDeleting] = useState(false)

    return <>
        <MyNavigationBar>{title}</MyNavigationBar>
        {data && <>
            <CellGroup divider={false} style={{position: "sticky", top: myNavigationBarHeight + 'px', zIndex: 999}}>
                <Cell>{data.createdBy.name}创建于{data.createdDateTime.format(DATE_WITH_HOUR_MINUTE_FORMATER)}</Cell>
                {data.submittedDateTime && <Cell title={"提交时间"}
                                                 extra={(data.submittedDateTime).format(DATE_WITH_HOUR_MINUTE_FORMATER)}></Cell>}
                {data.receiptDateTime && data.receiptId && <Cell title={"查看入库单"} extra={<ArrowRight/>} onClick={() => {
                    Taro.navigateTo({
                        url:`/pages/procurementReceiptDetail?id=${data?.receiptId}`
                    })
                }}></Cell>}
                {(canDelete || canSubmit || canReceipt) &&
                    <Cell extra={
                        <Space>
                            <Button onClick={async () => {
                                setExportToExcelDialogVisible(true)
                            }}>导出</Button>
                            <ExportToExcelConfigurationDialog
                                visible={exportToExcelDialogVisible}
                                rememberedColumnsStorageKey={PROCUREMENT_ITEMS_EXPORT_COLUMNS_KEY}
                                selectableColumns={columns}
                                onCancel={() => {
                                    setExportToExcelDialogVisible(false)
                                }}
                                onConfirm={async values => {
                                    let workbook = exportToWorkbook(data.items, columns.filter(it => values.includes(it.key)));
                                    await saveAndOpenWorkbook(workbook, `${data?.supplier.name}${(data.createdDateTime).format(DATE_WITH_TIME_FORMATER)}`)
                                    setExportToExcelDialogVisible(false)
                                }}/>
                            {canDelete &&
                                <Button type={"danger"} fill={"outline"} loading={deleting} onClick={async () => {
                                    setDeleting(true)
                                    try {
                                        await deleteProcurement(data.id)
                                        procurementPageStackStore.removeItemByKey(data.id)
                                        await Taro.navigateBack()
                                    } finally {
                                        setDeleting(false)
                                    }
                                }}>删除</Button>}
                            {canSubmit && <Button type={"primary"}
                                                  onClick={() => {
                                                      Taro.showModal({
                                                          title: "确定要提交吗",
                                                          content: "提交后你可能无法再修改"
                                                      }).then(result => {
                                                          if (result.confirm)
                                                              submitProcurement(procurementId!!).then(() => {
                                                                  procurementPageStackStore.updateDetail({
                                                                      ...data,
                                                                      submittedDateTime: OffsetDateTime.now(),
                                                                  })
                                                              })
                                                      })
                                                  }}>提交</Button>}
                            {canReceipt && <Button type={"primary"}
                                                 onClick={() => {
                                                     Taro.showModal({
                                                         title: "确定要入库吗",
                                                         content: "入库后你将无法再修改，且生成入库单"
                                                     }).then(result => {
                                                         if (result.confirm)
                                                             receiptProcurement(procurementId!!).then((response) => {
                                                                 procurementPageStackStore.updateDetail({
                                                                     ...data,
                                                                     receiptDateTime: OffsetDateTime.now(),
                                                                     receiptId:response.data,
                                                                 })
                                                             })
                                                     })
                                                 }}>入库</Button>}

                        </Space>
                    }/>}
            </CellGroup>
            {data.items.map((item, index) => {
                return <OrderListItem data={item}
                                      canEdit={canEdit}
                                      onClick={() => {
                                          Taro.navigateTo({url: `/pages/goodsDetail?id=${item.id}`})
                                      }}
                                      onDelete={async () => {
                                          if (!item.subGoods) {
                                              await deleteProcurementItem(procurementId!!, item.id)
                                          } else {
                                              await deleteProcurementItemSub(procurementId!!, item.id, item.subGoods.id)
                                          }
                                          ArrayUtils.remove(data!.items, item)
                                          procurementPageStackStore.updateDetail({
                                              ...data,
                                              items: Array.from(data?.items),
                                          })
                                      }}
                                      onUpdateAmount={async (value, unitId) => {
                                          if (!item.subGoods) {
                                              await updateProcurementItemAmount(procurementId!!, item.id, {
                                                  unitId,
                                                  amount: value
                                              });
                                          } else {
                                              await updateProcurementItemSubAmount(procurementId!!, item.id, {
                                                  unitId,
                                                  amount: value
                                              }, item.subGoods.id);
                                          }
                                          Taro.showToast({
                                              title: "修改数量成功！",
                                              icon: "success",
                                          })
                                          let items = Array.from(data!.items);
                                          items[index] = {
                                              ...items[index],
                                              amountInOrder: value,
                                              unit: items[index].units.find(it => it.id === unitId)
                                          }
                                          procurementPageStackStore.updateDetail({
                                              ...data,
                                              items: items
                                          })
                                      }}
                                      onUpdateNote={async (note) => {
                                          if (!item.subGoods) {
                                              await updateProcurementItemNote(procurementId!!, item.id, note)
                                          } else {
                                              await updateProcurementItemSubNote(procurementId!!, item.id, note, item.subGoods.id)
                                          }
                                          let items = Array.from(data!.items);
                                          items[index].note = note
                                          procurementPageStackStore.updateDetail({
                                              ...data,
                                              items: items
                                          })
                                      }}
                />
            })}
            {!!data && <View className={styles.bottomPlaceholder} >
                <SafeArea position={"bottom"}/>
            </View>}
            {!!data && <View className={styles.bottomBar}>
                <Space className={styles.bottomSpace}>
                    <Button fill={"outline"} icon={<Top/>} onClick={() => {
                        Taro.pageScrollTo({
                            scrollTop: 0,
                            duration: 300,
                        })
                    }}>回到顶部</Button>
                    {canEdit && <Button icon={<Add/>} type={"primary"} onClick={() => {
                        setSelectGoodsPopupVisible(true)
                    }}>添加{`(${data.items.length})`}</Button>}
                    {canEdit && <ScanBarcodeButton onScanSuccess={async (barcode, continueScan) => {
                        if (data.items.map(it => it.barcode).includes(barcode)) {
                            await barcodeRepeated(`订单中已存在此货品\t${barcode}`)

                            setTimeout(() => {
                                continueScan()
                            }, 100)
                            return
                        }
                        let response = await addProcurementItemFromBarcode(procurementId!!, barcode);
                        let item = response.data
                        let array = Array.from(data.items)
                        array.push({...item, id: item.goodsId})
                        procurementPageStackStore.updateDetail({...data, items: array})
                        await scanSuccess()
                        scrollToBottom()
                        // setTimeout(() => {
                        //     continueScan()
                        // }, 100)
                    }}>扫码</ScanBarcodeButton>}
                </Space>
                <SafeArea position={"bottom"}/>
            </View>}
        </>}
        <SelectGoodsPopup visible={selectGoodsPopupVisible} onClose={() => setSelectGoodsPopupVisible(false)}
                          existedGoodsList={data?.items}
                          editProcurementId={procurementId}
                          onConfirm={async value => {
            const response = (await addProcurementItemsFromSubGoodsKeyList(procurementId!, value))
            let array = Array.from(data?.items ?? [])
            procurementPageStackStore.updateDetail({
                ...data!,
                items: array.concat(response.data.map(item => ({...item, id: item.goodsId, subGoods: item.subGoods})))
            })
            setTimeout(() => {
                scrollToBottom()
            }, 300)
        }}/>
    </>
}

export default observer(ProcurementDetail)


